#include "VSMorphSequenceFunc.h"
#include "VSSwitchNode.h"
#include "VSMorphSet.h"
#include "VSGeometryNode.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VSMorphSequenceFunc,VSMorphFunction)
static bool gs_bStreamRegistered_VSMorphSequenceFunc= VSMorphSequenceFunc::RegisterMainFactory();
bool VSMorphSequenceFunc::ms_bRegisterMainFactory = false;
bool VSMorphSequenceFunc::RegisterMainFactory()
{
	if (!ms_bRegisterMainFactory)
	{ 
		VSMain::AddInitialFuntion(VSMorphSequenceFunc::InitialClassFactory); 
		ms_bRegisterMainFactory = true;
	} 
	return ms_bRegisterMainFactory;

}
bool VSMorphSequenceFunc::InitialClassFactory()
{
	ms_ClassFactory.AddElement(ms_Type.GetName(),FactoryFunc);

	return 1;
}
VSObject * VSMorphSequenceFunc::FactoryFunc()
{
	return VS_NEW VSMorphSequenceFunc;

}
bool VSMorphSequenceFunc::Register(VSStream & rStream)const
{
	if (rStream.IsObjectRegister(this))
	{
		return 1;
	}
	if(!VSMorphFunction::Register(rStream))
		return 0;

	return 1;
}
unsigned int VSMorphSequenceFunc::DiskUse()const
{
	unsigned int Used = VSMorphFunction::DiskUse();
	Used += VSStream::GetStrDistUse(m_MorphName);
	
	return Used;
}
bool VSMorphSequenceFunc::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSMorphFunction::Save(rStream,iSaveUse))
		return 0;

	if(!rStream.WriteString(m_MorphName))
		return 0;
	iSaveUse += VSStream::GetStrDistUse(m_MorphName);
	return 1;
}
bool VSMorphSequenceFunc::Load(VSStream & rStream,unsigned int &iSaveUse)
{	
	if(!VSMorphFunction::Load(rStream,iSaveUse))
		return 0;
	
	if(!rStream.ReadString(m_MorphName))
		return 0;
	iSaveUse += VSStream::GetStrDistUse(m_MorphName);
	return 1;
}
bool VSMorphSequenceFunc::Link(VSStream & rStream)
{
	if(!VSMorphFunction::Link(rStream))
		return 0;

	return 1;

}
bool VSMorphSequenceFunc::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSMorphSequenceFunc* Temp = DynamicCast<VSMorphSequenceFunc>(pObject); 
	if(!Temp)
		return 0;
	if(VSMorphFunction::Clone(pObject,uiType))
	{
		m_MorphName = Temp->m_MorphName;
		return 1;

	}
	else
	{
		return 0;
	}

}
VSMorphSequenceFunc::VSMorphSequenceFunc(const VSUsedName & ShowName,VSMorphTree * pMorphTree)
:VSMorphFunction(ShowName,pMorphTree)
{
	

	VSString OutputName = _T("Output");
	VSOutputNode * pOutputNode = NULL;
	pOutputNode = VS_NEW VSOutputNode(VSPutNode::AVT_MORPH,OutputName,this);
	VSMAC_ASSERT(pOutputNode);
	m_pOutput.AddElement(pOutputNode);

	m_uiRepeatType = VSController::RT_CYCLE;
}
VSMorphSequenceFunc::VSMorphSequenceFunc()
{

	m_uiRepeatType = VSController::RT_CYCLE;
}
VSMorphSequenceFunc::~VSMorphSequenceFunc()
{

}
void VSMorphSequenceFunc::SetMorph(VSString MorphName)
{
	m_MorphName = MorphName;
}
bool VSMorphSequenceFunc::UpdateEx(double dAppTime)
{
	
	if(!VSMorphFunction::UpdateEx(dAppTime))
		return false;
	
	return true;

}
void VSMorphSequenceFunc::UpdateVertexDate(unsigned int GeometryIndex,unsigned int uiVertexIndex)
{
	VSGeometryNode * pGeomeNode = NULL;
	VSModelMeshNode* pMeshNode = (VSModelMeshNode *)m_pOwner->GetMeshNode();

	if (!pMeshNode)
	{
		return ;
	}
	if (pMeshNode->GetLodType() == VSModelMeshNode::LT_DLOD)
	{
		if (pMeshNode->GetDlodNode())
		{
			pGeomeNode = DynamicCast<VSGeometryNode>(pMeshNode->GetDlodNode()->GetActiveNode());
		}
	}
	else
	{	
		pGeomeNode = DynamicCast<VSGeometryNode>(pMeshNode->GetChild(0));
	}
	if(!pGeomeNode)
		return ;
	const VSMorphSet * pMorphSet = pGeomeNode->GetMorphSet();
	if (!pMorphSet)
	{
		return;
	}

	VSMorph * pMorph = pMorphSet->GetMorph(m_MorphName);
	if (!pMorph)
	{
		return;
	}

	if (!pMorph->GetVertexNum(GeometryIndex))
	{
		return;
	}
	
	VSVertexBuffer * pVertexBuffer = pMorph->GetBuffer(GeometryIndex);

	
	for (unsigned int uiLevel = 0 ; uiLevel < VSMorphFunction::MAX_NUM_POS3 ; uiLevel++)
	{
		VSDataBuffer * pDate = pVertexBuffer->GetPositionDate(uiLevel);
		if (pDate)
		{
			VSVector3 * pPos = (VSVector3 *)pDate->GetDate();
			if (pPos)
			{
				pPos +=uiVertexIndex;
				SetPos(*pPos,uiLevel);
			}
			
		}
	}
	for (unsigned int uiLevel = 0 ; uiLevel < VSMorphFunction::MAX_NUM_TEXCOORD2 ; uiLevel++)
	{
		VSDataBuffer * pDate = pVertexBuffer->GetTexCoordDate(uiLevel);
		if (pDate)
		{
			VSVector2 * pTexcoord = (VSVector2 *)pDate->GetDate();
			if (pTexcoord)
			{
				pTexcoord +=uiVertexIndex;
				SetTexcoord(*pTexcoord,uiLevel);
			}

		}
	}
	for (unsigned int uiLevel = 0 ; uiLevel < VSMorphFunction::MAX_NUM_NORMAL3 ; uiLevel++)
	{
		VSDataBuffer * pDate = pVertexBuffer->GetNormalDate(uiLevel);
		if (pDate)
		{
			VSVector3 * pNormal = (VSVector3 *)pDate->GetDate();
			if (pNormal)
			{
				pNormal +=uiVertexIndex;
				SetNormal(*pNormal,uiLevel);
			}

		}
	}
	
	{
		VSDataBuffer * pDate = pVertexBuffer->GetTangentDate();
		if (pDate)
		{
			VSVector3 * pTangent = (VSVector3 *)pDate->GetDate();
			if (pTangent)
			{
				pTangent +=uiVertexIndex;
				SetTangent(*pTangent);
			}

		}
	
	}

	{
		VSDataBuffer * pDate = pVertexBuffer->GetBinormalDate();
		if (pDate)
		{
			VSVector3 * pBinormal = (VSVector3 *)pDate->GetDate();
			if (pBinormal)
			{
				pBinormal +=uiVertexIndex;
				SetBinormal(*pBinormal);
			}

		}

	}

	{
		VSDataBuffer * pDate = pVertexBuffer->GetPSizeDate();
		if (pDate)
		{
			VSREAL * pPSize = (VSREAL *)pDate->GetDate();
			if (pPSize)
			{
				pPSize +=uiVertexIndex;
				SetPSize(*pPSize);
			}

		}

	}
	for (unsigned int uiLevel = 0 ; uiLevel < VSMorphFunction::MAX_NUM_COLOR ; uiLevel++)
	{
		VSDataBuffer * pDate = pVertexBuffer->GetColorDate(uiLevel);
		if (pDate)
		{
			VSColorRGBA * pColor = (VSColorRGBA *)pDate->GetDate();
			if (pColor)
			{
				pColor +=uiVertexIndex;
				SetColor(*pColor,uiLevel);
			}

		}
	}

	{
		VSDataBuffer * pDate = pVertexBuffer->GetBlendWeightDate();
		if (pDate)
		{
			VSVector3W * pBlendWeight = (VSVector3W *)pDate->GetDate();
			if (pBlendWeight)
			{
				pBlendWeight +=uiVertexIndex;
				SetBlendWeight(*pBlendWeight);
			}

		}

	}
	{
		VSDataBuffer * pDate = pVertexBuffer->GetBlendIndicesDate();
		if (pDate)
		{
			VSVector3W * pBlendIndex = (VSVector3W *)pDate->GetDate();
			if (pBlendIndex)
			{
				pBlendIndex +=uiVertexIndex;
				SetBlendIndex(*pBlendIndex);
			}

		}

	}
}